package org.example.util;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Objects;

/**
 * UTC时间工具类.
 *
 * @author KazuHo
 * @version 1.0
 * @since 2021/12/5 21:46
 */
public final class TimeUtil {
    private static final DateTimeFormatter UTC_STAMP_FMT =
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'hh:mm:ss'Z'");

    private static final DateTimeFormatter FLD_FMT = DateTimeFormatter.ofPattern("yyyy_MM_dd");

    private static final ZoneId GMT_ZERO_ZONE = ZoneId.of("+00:00");

    private TimeUtil() {
    }

    public static String utcNow() {
        ZonedDateTime now = ZonedDateTime.ofInstant(Instant.now(), GMT_ZERO_ZONE);
        return UTC_STAMP_FMT.format(now);
    }

    public static String utcToday() {
        ZonedDateTime storeTimestamp = ZonedDateTime.ofInstant(Instant.now(), GMT_ZERO_ZONE);
        return FLD_FMT.format(storeTimestamp);
    }

    public static Long localDateTimeToTimeStamp(LocalDateTime dateTime, ZoneId zoneId) {
        Long res = null;
        if (Objects.isNull(zoneId)) {
            res = dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        } else {
            res = dateTime.atZone(zoneId).toInstant().toEpochMilli();
        }

        return res;
    }

    public static LocalDateTime localDataTimeFromString(String dateTime) {
        LocalDateTime res = null;
        if (!Objects.isNull(dateTime) && !"".equalsIgnoreCase(dateTime) && dateTime.contains("T")) {
            res = LocalDateTime.parse(dateTime);
        } else {
            res = LocalDateTime.parse(dateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        }

        return res;
    }

    public static LocalDateTime localDateTimeFromDate(Date date, ZoneId zoneId) {
        LocalDateTime res = null;
        if (Objects.isNull(zoneId)) {
            res = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
        } else {
            res = LocalDateTime.ofInstant(date.toInstant(), zoneId);
        }

        return res;
    }

    public ZonedDateTime localDateTimeToGmt(LocalDateTime localDateTime, ZoneId zoneId) {
        ZonedDateTime res = null;
        if (Objects.isNull(zoneId)) {
            ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
            res = zdt.withZoneSameInstant(ZoneId.of("+00:00"));
        } else {
            ZonedDateTime zdt = localDateTime.atZone(zoneId);
            res = zdt.withZoneSameInstant(ZoneId.of("+00:00"));
        }

        return res;
    }
}
